package models

import (
	"encoding/json"
	"mindonmap/pkgs/util"
	"strconv"
	"time"

	"github.com/jinzhu/gorm"
)

type Mindmap struct {
	Model
	Id             int    `json:"-"`
	State          int    `json:"state"`
	Acid           int    `json:"acid"`
	Mindid         string `json:"mindid"`
	Filename       string `json:"filename"`
	Mapdata        string `json:"mapdata"`
	Image          string `json:"image"`
	Sharestate     int    `json:"sharestate"`
	Modifietime    int    `json:"modifietime"`
	Createtime     int    `json:"createtime"`
	IsAi           int    `json:"is_ai"`
	IsAiResult     int    `json:"is_ai_result"`
	AiKey          string `json:"ai_key"`
	Lang           string `json:"lang"`
	UserStatus     int    `json:"user_status"`
	Version        int    `json:"version"`
	CreatePlatform string `json:"create_platform"`
	SavePlatform   string `json:"Save_platform"`
	//Types      string `json:"t"`
}
type MindmapTotal struct {
	Total int `json:"total"`
}

type mindmap struct {
	Model
	Id         int    `json:"-"`
	State      int    `json:"state"`
	Acid       int    `json:"acid"`
	Mindid     string `json:"mindid"`
	Filename   string `json:"filename"`
	Image      string `json:"image"`
	Sharestate int    `json:"sharestate"`
	Createtime int    `json:"createtime"`
}
type MindMaplist struct {
	Id         int    `json:"-"`
	State      int    `json:"state"`
	Acid       int    `json:"acid"`
	Mindid     string `json:"mindid"`
	Filename   string `json:"filename"`
	Image      string `json:"image"`
	Sharestate int    `json:"sharestate"`
	Checktype  int    `json:"checktype"`
	Createtime int    `json:"createtime"`
	Version    int    `json:"version"`
}

func (tag *Mindmap) BeforeCreate(scope *gorm.Scope) error {
	scope.SetColumn("createtime", time.Now().Unix())
	return nil
}

func (tag *Mindmap) BeforeUpdate(scope *gorm.Scope) error {
	scope.SetColumn("modifietime", time.Now().Unix())
	return nil
}

func GetMindMap(mindid string) (minds Mindmap) {
	db.Where("mindid = ?", mindid).First(&minds)
	//db.Model(&minds).Related(&minds.Tag)
	return
}

func CopyMindMap(mindid string) (minds Mindmap) {
	db.Where("mindid = ?", mindid).First(&minds)
	uuidStr, _ := util.UUIDv4()
	db.Create(&Mindmap{
		Acid:     minds.Acid,
		Mindid:   uuidStr,
		Filename: minds.Filename + "_copy",
		Mapdata:  minds.Mapdata,
		Image:    minds.Image,
		State:    minds.State,
	})
	return
}

func GetMindMapShare(mindid string) (minds Mindmap) {
	db.Where("state = 0 and mindid = ?", mindid).First(&minds)
	//db.Model(&minds).Related(&minds.Tag)
	return
}

func GetMindMapsTempate(PageNum int, PageSize int, maps interface{}) (minds []Mindmap) {
	db.Where(maps).Order("id desc").Offset(PageNum).Limit(PageSize).Find(&minds)
	return
}
func GetDelMindMaps(PageNum int, PageSize int, userid int) (minds []Mindmap) {
	db.Raw("(SELECT id,mindid,createtime,filename,image,acid,state,\"f\" AS types FROM md_mind_flow	WHERE acid = ? AND state = 1) UNION (SELECT id,mindid,createtime,filename,image,acid,state,\"m\" AS types FROM md_mindmap WHERE acid = ? AND state = 1)", userid, userid).Order("createtime desc").Offset(PageNum).Limit(PageSize).Find(&minds)
	return
}

func GetDelMindMapsV5(PageNum int, PageSize int, userid int) (minds []Mindmap) {
	db.Raw("(SELECT id,mindid,createtime,filename,image,acid,state,\"f\" AS types FROM md_mind_flow	WHERE acid = ? AND state = 1) UNION (SELECT id,mindid,createtime,filename,image,acid,state,\"m\" AS types FROM md_mindmap WHERE version = 1 AND acid = ? AND state = 1)", userid, userid).Order("createtime desc").Offset(PageNum).Limit(PageSize).Find(&minds)
	return
}
func GetMindMapTotal(userid int) (minds MindmapTotal) {
	db.Raw("SELECT SUM(mm) AS total FROM ((SELECT count(*) AS mm FROM md_mind_flow	WHERE acid = ? AND state in(0,1)) UNION all (SELECT count(*) AS mm FROM md_mindmap WHERE version = 1 AND acid = ? AND state in(0,1))) mm", userid, userid).Find(&minds)
	return
}

func GetMindMapTotalV5(userid int) (minds MindmapTotal) {
	db.Raw("SELECT SUM(mm) AS total FROM ((SELECT count(*) AS mm FROM md_mind_flow	WHERE acid = ? AND state in(0,1)) UNION all (SELECT count(*) AS mm FROM md_mindmap WHERE acid = ? AND state in(0,1))) mm", userid, userid).Find(&minds)
	return
}

func GetMindMapslist(PageNum int, PageSize int, userid int, order string) (minds []MindMaplist) {
	db.Raw("SELECT map.id,map.mindid,shares.shareid,map.createtime,shares.checktype,map.filename,map.image,map.acid,map.sharestate,map.version FROM md_mindmap AS map left JOIN md_mind_share AS shares ON map.mindid = shares.pid WHERE map.version = 1 and map.state = 0 and map.acid = ? ", userid).Order(order).Offset(PageNum).Limit(PageSize).Scan(&minds)

	currentTimestamp := time.Now().Unix()
	for i := range minds {
		minds[i].Image = minds[i].Image + "?" + strconv.FormatInt(currentTimestamp, 10)
	}

	return
}

func GetMindMapslistV5(PageNum int, PageSize int, userid int, order string) (minds []MindMaplist) {
	db.Raw("SELECT map.id,map.mindid,shares.shareid,map.createtime,shares.checktype,map.filename,map.image,map.acid,map.sharestate,map.version FROM md_mindmap AS map left JOIN md_mind_share AS shares ON map.mindid = shares.pid WHERE map.state =0 and map.acid = ? ", userid).Order(order).Offset(PageNum).Limit(PageSize).Scan(&minds)

	currentTimestamp := time.Now().Unix()
	for i := range minds {
		minds[i].Image = minds[i].Image + "?" + strconv.FormatInt(currentTimestamp, 10)
	}

	return
}

func AddMindMap(data map[string]interface{}) bool {
	db.Create(&Mindmap{
		Acid:       data["acid"].(int),
		Mindid:     data["mindid"].(string),
		Filename:   data["filename"].(string),
		Mapdata:    data["mapdata"].(string),
		Image:      data["image"].(string),
		State:      data["state"].(int),
		UserStatus: data["user_status"].(int),
		Version:    1,
	})
	return true
}

func AddMindMap2(data map[string]interface{}) bool {
	db.Create(&Mindmap{
		Acid:           data["acid"].(int),
		Mindid:         data["mindid"].(string),
		Filename:       data["filename"].(string),
		Image:          data["image"].(string),
		State:          data["state"].(int),
		AiKey:          data["ai_key"].(string),
		IsAi:           data["is_ai"].(int),
		IsAiResult:     data["is_ai_result"].(int),
		Lang:           data["lang"].(string),
		UserStatus:     data["user_status"].(int),
		CreatePlatform: data["create_platform"].(string),
		Version:        2,
	})
	return true
}

func ShareAddMindMap(data map[string]interface{}) bool {
	db.Create(&Mindmap{
		Acid:     data["acid"].(int),
		Mindid:   data["mindid"].(string),
		Filename: data["filename"].(string),
		Image:    data["image"].(string),
		State:    data["state"].(int),
		Mapdata:  data["mapdata"].(string),
		Version:  2,
	})
	return true
}

func EditMindMap(mindid string, maps interface{}) bool {
	db.Model(&Mindmap{}).Where("mindid = ?", mindid).Update(maps)

	newValue, _ := json.Marshal(maps)
	util.WriteLog("UPDATE `md_mindmap` SET " + string(newValue) + " where mindid=" + mindid)
	return true
}

func DeleteMindMap(mindid string, maps interface{}) bool {
	db.Model(&Mindmap{}).Where("mindid = ?", mindid).Update(maps)
	return true
}
func DeleteMindMaps(mindid interface{}, userid int, maps interface{}) bool {
	db.Model(&Mindmap{}).Where("acid = ? and mindid in (?)", userid, mindid).Update(maps)
	return true
}
func DeleteAllMindMaps(userid int, maps interface{}) bool {
	db.Model(&Mindmap{}).Where("acid = ? and state = 1", userid).Update(maps)
	db.Model(&MindFlow{}).Where("acid = ? and state = 1", userid).Update(maps)
	return true
}
func ExistMindMapByIDs(mindid string) bool {
	var minds Mindmap
	db.Where("mindid = ?", mindid).First(&minds)
	if minds.ID > 0 {
		return true
	}
	return false
}
func ExistMindMapByID(mindid string, userid int) bool {
	var minds Mindmap
	db.Where("mindid = ? and acid = ?", mindid, userid).First(&minds)
	if minds.ID > 0 {
		return true
	}
	return false
}
func ExistMindMapAndFlowByID(mindid string, types string) bool {
	if types == "m" {
		var minds Mindmap
		db.Where("mindid = ?", mindid).First(&minds)
		if minds.ID > 0 {
			return true
		}
	} else if types == "f" {
		var minds MindFlow
		db.Where("mindid = ?", mindid).First(&minds)
		if minds.ID > 0 {
			return true
		}
	}

	return false
}
func ExistMindMapByMindID(id string) bool {
	var minds Mindmap
	db.Where("mindid = ?", id).First(&minds)
	if minds.ID > 0 {
		return true
	}
	return false
}

func GetMindMapID(mindid string) string {
	var minds Mindmap
	db.Where("mindid = ?", mindid).First(&minds)
	if minds.ID > 0 {
		return minds.Mindid
	}
	return ""
}
func UpdateAiStatus(userid int, task_id string, mind_id string, lang string) bool {
	// 方法一：使用 Map 更新多个字段
	updateData := map[string]interface{}{
		"is_ai_result": 1,
		"lang":         lang,
	}
	updateData2 := map[string]interface{}{
		"mind_id": mind_id,
	}
	db.Model(&MindmapAi{}).Where("acid = ? and task_id = ?", userid, task_id).Update(updateData2)

	db.Model(&Mindmap{}).Where("acid = ? and mindid = ?", userid, mind_id).Update(updateData)
	return true
}

func GetMindMapDelTotal(userid int) (count int) {
	//db.Model(&Mindmap{}).Where(maps).Count(&count)
	//db.Raw("SELECT SUM(c) from ((SELECT COUNT(id) as c FROM md_mind_flow WHERE acid = ? AND state = 1) UNION (SELECT COUNT(id) as c FROM md_mindmap WHERE acid = ? AND state = 1) ) as d", userid, userid).Count(&count)
	db.Raw("(SELECT COUNT(id) as c FROM md_mind_flow WHERE acid = ? AND state = 1) UNION (SELECT COUNT(id) as c FROM md_mindmap WHERE version = 1 AND acid = ? AND state = 1)", userid, userid).Count(&count)

	return
}

func GetMindMapDelTotalV5(userid int) (count int) {
	//db.Model(&Mindmap{}).Where(maps).Count(&count)
	//db.Raw("SELECT SUM(c) from ((SELECT COUNT(id) as c FROM md_mind_flow WHERE acid = ? AND state = 1) UNION (SELECT COUNT(id) as c FROM md_mindmap WHERE acid = ? AND state = 1) ) as d", userid, userid).Count(&count)
	db.Raw("(SELECT COUNT(id) as c FROM md_mind_flow WHERE acid = ? AND state = 1) UNION (SELECT COUNT(id) as c FROM md_mindmap WHERE acid = ? AND state = 1)", userid, userid).Count(&count)

	return
}

func GetMindMapDetail(md_id int) (minds []mindmap, err error) {
	result := db.Select("id,mindid,image").Where("state = 0 and id = ?", md_id).First(&minds)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			// 未找到记录
			return nil, nil
		}
		// 其他错误
		return nil, result.Error
	}
	return minds, nil
}
